package com.feri.ikun.service.impl;

import cn.hutool.crypto.SecureUtil;
import cn.hutool.crypto.symmetric.SymmetricAlgorithm;
import cn.hutool.crypto.symmetric.SymmetricCrypto;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.feri.ikun.dao.UserDao;
import com.feri.ikun.dto.UserAddDto;
import com.feri.ikun.dto.UserFindDto;
import com.feri.ikun.dto.UserLoginDto;
import com.feri.ikun.entity.User;
import com.feri.ikun.service.intf.UserService;
import com.feri.ikun.util.JedisUtil;
import com.feri.ikun.util.PassUtil;
import com.feri.ikun.vo.R;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.util.Base64;
import java.util.Date;

/**
 * ━━━━━━神兽出没━━━━━━
 * 　　　┏┓　　　┏┓
 * 　　┏┛┻━━━┛┻┓
 * 　　┃　　　　　　 ┃
 * 　　┃　　　━　　　┃
 * 　　┃　┳┛　┗┳　  ┃
 * 　　┃　　　　　　 ┃
 * 　　┃　　　┻　　　┃
 * 　　┃　　　　　　　┃
 * 　　┗━┓　　　┏━┛Code is far away from bug with the animal protecting
 * 　　　　┃　　　┃    神兽保佑,代码无bug
 * 　　　　┃　　　┃
 * 　　　　┃　　　┗━━━┓
 * 　　　　┃　　　　　　　┣┓
 * 　　　　┃　　　　　　　┏┛
 * 　　　　┗┓┓┏━┳┓┏┛
 * 　　　　　┃┫┫　┃┫┫
 * 　　　　　┗┻┛　┗┻┛
 * ━━━━━━永无BUG!━━━━━━
 *
 * @Description:
 * @Author: 邢朋辉
 * @Date: 2022/12/7 14:41
 */
@Service
public class UserServiceImpl implements UserService {
    @Resource
    private UserDao dao;
    private final String PASS_KEY="PvDCLxg7IkwBr/idSiOWcA==";

    @Override
    public R checkPhone(String phone) {
        //1.参数校验
        if(StringUtils.hasLength(phone)){
            //2.手机号 正则校验 符合手机号格式
            if(phone.matches("^1[3456789]\\d{9}$")){
                //3.查询数据库并完成校验
                if(dao.selectOne(new QueryWrapper<User>().eq("phone",phone))==null){
                    return R.ok();
                }
            }
        }
        return R.fail("亲，输入的手机号不合规！");
    }

    @Override
    public R checkName(String name) {
        //1.参数校验
        if(StringUtils.hasLength(name)){
                //2.查询数据库并完成校验
                if(dao.selectOne(new QueryWrapper<User>().eq("name",name))==null){
                    return R.ok();
                }
        }
        return R.fail("亲，输入的昵称不合规！");
    }

    //预留一个问题：如何解决没有校验验证码就就注册的行为？
    @Override
    public R register(UserAddDto dto) {
        //1.校验
        if(dto!=null){
            if(StringUtils.hasLength(dto.getPhone()) && StringUtils.hasLength(dto.getName())){

                //2.校验手机号或用户名 是否存在
                QueryWrapper<User> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("phone",dto.getPhone()).or().eq("name",dto.getName());
                if(dao.selectOne(queryWrapper)==null){
                    User user=new User();
                    //3.可用 注册 密码转为密文  AES算法（对称加解密算法）
                    user.setPassword(PassUtil.aesEnc(PASS_KEY,dto.getPassword()));
                    user.setName(dto.getName());
                    user.setPhone(dto.getPhone());
                    user.setFlag(1);
                    user.setCtime(new Date());
                    //4.校验 改手机号 是否成功验证过 验证码
                    if(JedisUtil.existsSet("auth:checkphones",dto.getPhone())) {
                        //5.操作数据库
                        if (dao.insert(user) > 0) {
                            //6.注册成功,删除掉，原来记录的验证成功的手机号
                            JedisUtil.delSet("auth:checkphones",dto.getPhone());

                            return R.ok();
                        }
                    }
                }
            }
        }
        return R.fail("注册异常！");
    }

    //登录：手机号、用户名
    @Override
    public R loginAccount(UserLoginDto dto) {
        //1.校验
        if(dto!=null){
            if(StringUtils.hasLength(dto.getAccount())&& StringUtils.hasLength(dto.getPassword())){

                //2.查询
                QueryWrapper<User> queryWrapper=new QueryWrapper<>();
                queryWrapper.eq("phone",dto.getAccount()).or().eq("name",dto.getAccount());
                User user=dao.selectOne(queryWrapper);

                //3.校验 账号 是否存在
                if(user!=null){

                    // 手机号或用户名存在，
                    //4.校验密码，密文进行比较
                    if(user.getPassword().equals(PassUtil.aesEnc(PASS_KEY,dto.getPassword()))){

                        //5.登录成功 令牌：登录成功的标识，可以很简单，也可以很复杂 令牌存储起来，一般还有 有效期
                        String token=user.getId()+"";
                        JedisUtil.addStr("auth:token:"+user.getPhone(),token,1800);
                        //6.返回 记得把令牌返回
                        return R.ok(token);
                    }
                }
            }
        }
        return R.fail("亲，账号或密码不正确！");
    }

    @Override
    public R loginCode(UserLoginDto dto) {
        //1.验证
        if(dto!=null){
            if(StringUtils.hasLength(dto.getAccount())){
                //2.实现数据库的查询
                User user=dao.selectOne(new QueryWrapper<User>().eq("phone",dto.getAccount()));
                if(user!=null){
                    //3.手机号存在1 再校验是否有验证码
                    if(JedisUtil.existsKey("auth:login:"+dto.getAccount())){

                        //4.比较验证码
                        if(JedisUtil.getStr("auth:login:"+dto.getAccount()).equals(dto.getPassword())){
                            //5.成功  生成令牌 存储到Redis
                            String token=user.getId()+"";

                            JedisUtil.addStr("auth:token:"+user.getPhone(),token,1800);

                            //6.删除验证码 保证一次性
                            JedisUtil.delKeys("auth:login:"+user.getPhone());
                            //7.返回 记得把令牌返回
                            return R.ok(token);
                        }
                    }
                }
            }
        }
        return R.fail("亲，账号或验证码不正确！");
    }

    @Override
    public R findPass(UserFindDto dto) {
        //1.校验
        if(dto!=null){
            //2.验证是否存在 验证码
            String key="auth:find:"+dto.getPhone();
            if(JedisUtil.existsKey(key)){

                //3.校验验证码
                if(JedisUtil.getStr(key).equals(dto.getCode())){
                    //4.修改密码
                    if(dao.updatePass(PassUtil.aesEnc(PASS_KEY,dto.getPassword()),dto.getPhone())>0){
                        //5.删除验证码
                        JedisUtil.delKeys(key);
                        return R.ok();
                    }
                }
            }
        }
        return R.fail("亲，密码找回失败！请反思！");
    }

    @Override
    public R checkToken(String phone,String token) {
        //1.校验
        if(StringUtils.hasLength(phone)){
            //2.验证是否存在
            if(JedisUtil.existsKey("auth:token:"+phone)){
                //3.在比对 令牌的内容
                if(token.equals(JedisUtil.getStr("auth:token:"+phone))){

                    return R.ok();
                }
            }
        }
        return R.fail();
    }

    @Override
    public R all() {
        return R.ok(dao.selectList(null));
    }
}
